package com.yd.redis_storage_client.util;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class JedisByteHashMap implements Map<byte[], byte[]>, Cloneable,
	Serializable {
    private static final long serialVersionUID = -6971431362627219416L;
    private Map<ByteArrayWrapper, byte[]> internalMap = new HashMap<ByteArrayWrapper, byte[]>();

    public void clear() {
	internalMap.clear();
    }

    public boolean containsKey(Object key) {
	if (key instanceof byte[])
	    return internalMap.containsKey(new ByteArrayWrapper((byte[]) key));
	return internalMap.containsKey(key);
    }

    public boolean containsValue(Object value) {
	return internalMap.containsValue(value);
    }

    public Set<java.util.Map.Entry<byte[], byte[]>> entrySet() {
	Iterator<java.util.Map.Entry<ByteArrayWrapper, byte[]>> iterator = internalMap
		.entrySet().iterator();
	HashSet<Entry<byte[], byte[]>> hashSet = new HashSet<java.util.Map.Entry<byte[], byte[]>>();
	while (iterator.hasNext()) {
	    Entry<ByteArrayWrapper, byte[]> entry = iterator.next();
	    hashSet.add(new JedisByteEntry(entry.getKey().data, entry
		    .getValue()));
	}
	return hashSet;
    }

    public byte[] get(Object key) {
	if (key instanceof byte[])
	    return internalMap.get(new ByteArrayWrapper((byte[]) key));
	return internalMap.get(key);
    }

    public boolean isEmpty() {
	return internalMap.isEmpty();
    }

    public Set<byte[]> keySet() {
	Set<byte[]> keySet = new HashSet<byte[]>();
	Iterator<ByteArrayWrapper> iterator = internalMap.keySet().iterator();
	while (iterator.hasNext()) {
	    keySet.add(iterator.next().data);
	}
	return keySet;
    }

    public byte[] put(byte[] key, byte[] value) {
	return internalMap.put(new ByteArrayWrapper(key), value);
    }

    @SuppressWarnings("unchecked")
    public void putAll(Map<? extends byte[], ? extends byte[]> m) {
	Iterator<?> iterator = m.entrySet().iterator();
	while (iterator.hasNext()) {
	    Entry<? extends byte[], ? extends byte[]> next = (Entry<? extends byte[], ? extends byte[]>) iterator
		    .next();
	    internalMap.put(new ByteArrayWrapper(next.getKey()),
		    next.getValue());
	}
    }

    public byte[] remove(Object key) {
	if (key instanceof byte[])
	    return internalMap.remove(new ByteArrayWrapper((byte[]) key));
	return internalMap.remove(key);
    }

    public int size() {
	return internalMap.size();
    }

    public Collection<byte[]> values() {
	return internalMap.values();
    }

    private static final class ByteArrayWrapper {
	private final byte[] data;

	public ByteArrayWrapper(byte[] data) {
	    if (data == null) {
		throw new NullPointerException();
	    }
	    this.data = data;
	}

	public boolean equals(Object other) {
	    if (!(other instanceof ByteArrayWrapper)) {
		return false;
	    }
	    return Arrays.equals(data, ((ByteArrayWrapper) other).data);
	}

	public int hashCode() {
	    return Arrays.hashCode(data);
	}
    }

    private static final class JedisByteEntry implements Entry<byte[], byte[]> {
	private byte[] value;
	private byte[] key;

	public JedisByteEntry(byte[] key, byte[] value) {
	    this.key = key;
	    this.value = value;
	}

	public byte[] getKey() {
	    return this.key;
	}

	public byte[] getValue() {
	    return this.value;
	}

	public byte[] setValue(byte[] value) {
	    this.value = value;
	    return value;
	}

    }
}